/**
 * @Description: axios二次封装
 * @Version: 1.0
 * @Author: 琴时
 * @Date: 2021-11-17 15:53:23
 * @LastEditors: 琴时
 * @LastEditTime: 2021-11-22 23:45:52
 * @FilePath: \pt-utils\vue-demo\src\util\request.js
 */

/**
 * 接收响应数据有两种方式+
 * 1.使用链式操作来接收.then(res=>{}).catch(err=>{})
 * 2.使用async await来接收建议外层搭配上try catch
 */
import axios from 'axios'
import qs from 'qs'
import Vue from 'vue' //vue配合elementUI消息提示组件使用
// import { message } from 'antd'//react-PC端配合antd消息提示组件使用
// import { Toast } from 'antd-mobile'//react-移动端配合antd-mobile消息提示组件使用
// 请求超时[config]:showTimeout    1.[true]:显示提示 2.["again"]:显示再次提示弹出框
axios.defaults.timeout = 30000 //设置超时时间
axios.defaults.withCredentials = true //允许跨域携带凭证
axios.defaults.headers['Access-Control-Allow-Origin'] = '*'
axios.defaults.headers['Access-Control-Allow-Methods'] =
  'GET, POST, PATCH, PUT, DELETE, OPTIONS'
axios.defaults.headers['Access-Control-Allow-Headers'] =
  'Origin, Content-Type, X-Auth-Token'
axios.defaults.headers.get['X-Requested-With'] = 'XMLHttpRequest' //Ajax get请求标识
axios.defaults.headers.post['X-Requested-With'] = 'XMLHttpRequest' //Ajax post请求标识
axios.defaults.headers.post['Content-Type'] =
  'application/x-www-form-urlencoded;charset=utf-8' //POST请求参数获取不到的问题
axios.defaults.headers.post['Accept'] = 'application/json' //POST请求参数获取不到的问题
axios.defaults.headers.put['X-Requested-With'] = 'XMLHttpRequest' //Ajax put请求标识
axios.defaults.headers.delete['X-Requested-With'] = 'XMLHttpRequest' //Ajax delete请求标识

/**
 * 根据环境变量区分请求服务器根地址
 */
console.log('测试当前环境:', process.env.NODE_ENV || 'development')
/* axios请求拦截器 */
axios.interceptors.request.use(config => {
  let user = window.sessionStorage.getItem('userLogin') //TODO:根据自己项目需求修改
  /* 利用缓存的登录信息设置请求头 */
  try {
    if (user) {
      user = JSON.parse(user)
      config.headers.get['loginUserId'] = user.userId
      config.headers.post['loginUserId'] = user.userId
      config.headers.put['loginUserId'] = user.userId
      config.headers.delete['loginUserId'] = user.userId
      /* 携带token值 */
      const Authorization = user.token
      if (Authorization) {
        config.headers.Authorization = Authorization
      }
    }
    //get请求添加附带时间戳参数
    if (config.method == 'get') {
      config.params = {
        ...config.params,
        _t: Date.parse(new Date()) / 1000,
      }
    }
  } catch (error) {
    console.log('请求异常:', error)
  } finally {
    return config
  }
})
/* axios响应拦截器 */
axios.interceptors.response.use(
  res => {
    return res.data
  },
  error => {
    const { response } = error
    if (response) {
      /* 根据状态码自定义处理 */
      switch (response.status) {
        case 401: //=>权限问题
          break
        case 403: //服务器拒绝执行（token过期了）
          break
        case 404: //请求失败，未找到
          break
        default:
          console.log('服务器异常响应:', response)
      }
      Vue.prototype.$message({
        type: 'error',
        message: '系统繁忙,请联系管理员!',
      }) //vue+elementUI
      // message.error('系统繁忙,请联系管理员!',1) //react-PC端+antd
      // Toast.fail('系统繁忙,请联系管理员!',1) //react-移动端+antd-mobile
      return Promise.reject(response.data)
    } else {
      if (!window.navigator.onLine) {
        Vue.prototype.$message({
          type: 'error',
          message: '请连接网络!',
        }) //vue+elementUI
        // message.error('系统繁忙,请联系管理员!',1) //react-PC端+antd
        // Toast.fail('系统繁忙,请联系管理员!',1) //react-移动端+antd-mobile
        /* 断网处理 */
        return Promise.reject(response)
      }
      return Promise.reject(response)
    }
  }
)
export default axios //默认导出原对象

/*******
 * @description: 对 (get post put delete) 方法进行二次封装
 * @author: 琴时
 * @param {url} 请求路径
 * @param {formData} 请求数据体/body参数
 * @param {params} get-路径参数
 * @param {config} 请求头参数
 * @return {Promise} 服务器响应后再二次处理好的Promise对象
 */

/* 增 */
/**
 * 默认'Content-Type': 'application/json'，可在头部参数config中，修改Content-Type
 */
export const post = (url, formData, params, config = {}) => {
  return new Promise((resolve, reject) => {
    axios
      .post(url, formData, { params: params, ...config })
      .then(res => {
        resolve(res)
      })
      .catch(err => {
        reject(err)
      })
  })
}

/* 删 */
export const remove = (url, params, config = {}) => {
  return new Promise((resolve, reject) => {
    axios
      .delete(url, { params: params, ...config })
      .then(res => {
        resolve(res)
      })
      .catch(err => {
        reject(err)
      })
  })
}

/* 改 */
export const update = (url, formData, params, config = {}) => {
  return new Promise((resolve, reject) => {
    axios
      .put(url, formData, { params: params, ...config })
      .then(res => {
        resolve(res)
      })
      .catch(err => {
        reject(err)
      })
  })
}

/* 查 */
export const query = (url, params, config = {}) => {
  return new Promise((resolve, reject) => {
    axios
      .get(url, { params: params, ...config })
      .then(res => {
        console.log('测试res:', res)
        resolve(res)
      })
      .catch(err => {
        console.log('测试err:', err)
        reject(err)
      })
  })
}

/* 表单形式提交:请求头config 上面已设置Content-Type默认application/x-www-form-urlencoded;charset=UTF-8 */
export const postForm = (url, formData, params, config = {}) => {
  return new Promise((resolve, reject) => {
    axios
      .post(url, qs.stringify(formData), { params: params, ...config })
      .then(res => {
        resolve(res)
      })
      .catch(err => {
        reject(err)
      })
  })
}
